/*
 * DogeCore.java
 *
 * Created on 15 luglio 2007, 12.56
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */



package dogeCore;

import dogeDB.*;
import dogeScan.*;
import java.awt.Image;
import java.io.IOException;
import java.sql.*;
import java.util.Observable;
import java.util.Vector;

/**
 *
 * @author daniele
 */
public class DogeCore extends Observable {

    /** Creates a new instance of DogeCore */
    public DogeCore(DogeDB database) {
        //initializes database instance
        this.database=database;
        //no binary data for insertion
        this.binaryData=null;
    }
    
    /** Asks DogeDB to login 
        returns true for succesful login, false for login error
     */
    public void doLogin(String username, char[] password) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException{
        //calls DogeDB to perform login operations
        database.doLogin(username,password);
        //blanks password reference for security purposes
        password=null;
        //(if no exception is thrown) set username and get permissions for that user
        this.username=username;
        permissions=database.getPermissions();
    }

    /** returns whether insertion operations are allowed or not for current user*/
    public boolean insertAllowed(){
        return permissions[0];
    }
    /** returns whether editing operations are allowed or not for current user*/
    public boolean editAllowed(){
        return permissions[1];
    }
    /** returns whether viewing operations are allowed or not for current user*/
    public boolean searchAllowed(){
        return permissions[2];
    }
    /** returns current username */
    public String getUsername() throws UserNotLoggedException {
        if (username!=null){
            return username;
        } else {
            throw (new UserNotLoggedException());
        }

    }
    
    /** returns current user's department */
    public String getDepartment() throws UserNotLoggedException{
        if (username!=null){
            return database.getDepartment();
        } else {
            throw (new UserNotLoggedException());
        }        
    }
    
    /** Asks DogeDB to log out */
    public void doLogout() throws SQLException {
        //ask DogeDB to perform logout
        database.doLogout();
        //blanks data of the old user
        username=null;
        permissions=null;
    }

    /** Gets document types from database */
    public Vector getDocumentTypes() throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        return database.getDocumentTypes();
    }

    /** Gets communication subjects from database */
    public Vector getSubjects() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
        return database.getSubjects();
    }

    /** Gets users which can create documents from database */
    public Vector getCreators() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
        return database.getCreators();
    }

    /** Gets departments from database */
    public Vector getDepartments() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
        return database.getDepartments();
    }
        
    /** returns if binary data has been acquired */
    public boolean binaryDataAcquired() {
        return !(binaryData==null);
    }
    
    /** creates a new subject */
    public void addNewSubject(String newItem) throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        database.addNewSubject(prepareString(newItem,256));
    }

    /** manipulates a string to adapt it to the database
     *  @param string: the string to manipulate
     *  @param stringLength: the maximum length the string should be (e.g. due to db fields limitations) - O = no limits
     */
    private String prepareString(String string, int stringLength) {
        //trim blanks from beginning and end of the string...
        string=string.trim();
        //... and truncate it to stringLength characters due to database field size
        if (stringLength>0 && string.length()>stringLength) {
            string=string.substring(0,stringLength);
        }
        //quotes "'" doubling them because they are string delimiters in query syntax
        string=string.replaceAll("'","''");
        return string;
    }

    /** completes informations in parameter record and calls DogeDB to insert data */
    public String insertRecord(DogeRecord record) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
        //completes information in DogeRecord (and prepares strings to be inserted in database (using prepareString))
        //set current username (who is inserting the document...)
        record.setInsertionOperator(prepareString(username,16));
        //set department if it is automatically determined
        if (record.getDepartment()==null){
            record.setDepartment(department);
        }
        //set filename
        record.setBinaryFileName(prepareString(getFilename(),256));
        
        //set mimetype
        record.setBinaryMime(prepareString(binaryMime,50));
        
        //prepare the other strings to be inserted in database (using prepareString)
        if (! (record.getCreator()==null)){
            record.setCreator(prepareString(record.getCreator(),16));
        }
        record.setDepartment(prepareString(record.getDepartment(),50));
        record.setDescription(prepareString(record.getDescription(),0));
        record.setDocumentType(prepareString(record.getDocumentType(),50));
        record.setFromSubject(prepareString(record.getFromSubject(),256));
        record.setToSubject(prepareString(record.getToSubject(),256));
        //record.setDocumentNumber(database.getDocumentNumber(record.getFromSubject(),record.getToSubject()));
        record.setBinaryData(binaryData);
        
        //send prepared data to database
        String protocol=database.insertRecord(record);

        //manipulate answer string to remove doubled "'"
        protocol=protocol.replaceAll("''","'");
        return protocol;
    }

    /** gets file basename from binaryDataPath */
    private String getFilename() {
        //split path in subcomponents 
        String[] path=binaryDataPath.split("/");
        //return the last part of the path (the file basename)
        return path[path.length-1];
    }

    /** terminates DoGe gracefully */
    public void terminateDoge() throws SQLException {
        database.doLogout();
    }

    /** associates DogeCore to a scanner from which acquire docuemnts */
    public void setScanner(DogeScan scanner) {
        this.scanner=scanner;
    }

    /** return a new page from the scanner */
    public void scanNewPage() throws IOException {
        scanner.scanNewPage();
    }

    /** scan again the last page scanned */
    public void rescanLastPage() throws IOException {
        scanner.rescanLastPage();
    }

    /** return the number of scanned pages */
    public int getScannedPages(){
        return scanner.getScannedPages();
    }

    /** return the binary data scanned */
    public byte[] getScannedImage() {
        return binaryData;
    }
    
    /** return a preview of the last scan operation */
    public byte[] getPreview(){
        return scanner.getLastScannedImage();
    }
    
    /** save in DogeCore the image scanned by the scanner  */
    public void saveScannedImage() {
        //gets scanned image data and informations
        this.binaryDataPath=scanner.getDataPath();
        this.binaryData=scanner.getScannedImage();
        this.binaryMime=scanner.getScannedMime();
        //notify observers that scanned image is changed
        inform();
    }
    
    /** inform observers of a change in this object */
    private void inform(){
        setChanged();
        notifyObservers();
    }

    /** cleanup insertion-related data contained in DogeCore */
    public void cleanUpData() {
        //resets binary data and its pathname
        binaryDataPath=null;
        binaryData=null;
    }
    
    //permissions array for inserting, editing or viewing data
    private boolean permissions[];
    //username
    private String username;
    //database
    private DogeDB database;
    //current user department
    private String department;
    //binary data path
    private String binaryDataPath;
    //binary data
    private byte[] binaryData;
    //scanner
    private DogeScan scanner;
    //mimetype of the binary data
    private String binaryMime;
}
